package com.bball.court.ui.fragment;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.List;
import java.util.Locale;

import android.app.Fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.FragmentActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.bball.court.FaCApplication;
import com.bball.court.FaCConfiguration;
import com.bball.court.PreferenceHelper;
import com.bball.court.R;
import com.bball.court.service.UploaderService;
import com.bball.court.ui.NavigationUtil;
import com.bball.court.ui.view.StreamDrawable;
import com.bball.court.util.BitmapUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class FormFragment extends Fragment {

    public static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

    protected Uri fileUri;

    private LocationClient locationClient;
    private boolean pictureTaken = false;

    private EditText editTextTitle;
    private ImageView imageView;
    private ImageView imageViewUserProfile;
    private MapView mapView;
    private Location lastLocation;
    private Geocoder geocoder;
    private String[] adresse = new String[3];

    public static Fragment newFragment() {
        return new FormFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        geocoder = new Geocoder(getActivity(), Locale.getDefault());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.form_fragment, container, false);
        setHasOptionsMenu(true);
        editTextTitle = (EditText) view.findViewById(R.id.editTextTitle);
        editTextTitle.addTextChangedListener(watcher);
        imageView = (ImageView) view.findViewById(R.id.imageView1);
        imageView.setOnClickListener(onClickListener);
        TextView textViewUserName = (TextView) view.findViewById(R.id.textViewUserName);
        textViewUserName.setText(PreferenceHelper.getUserName(getActivity()));
        imageViewUserProfile = (ImageView) view.findViewById(R.id.imageViewUserProfile);
        mapView = (MapView) view.findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        getActivity().getActionBar().setTitle(R.string.court_s_suggestion);
        locationClient = (LocationClient) getActivity().getApplicationContext().getSystemService(FaCApplication.LOCATION_CLIENT);
        if (locationClient.isConnected()) {
            lastLocation = locationClient.getLastLocation();
            if (lastLocation != null) {
                double latitude = lastLocation.getLatitude();
                double longitude = lastLocation.getLongitude();
                try {
                    List<Address> addresses = geocoder.getFromLocation(latitude, longitude, 1);
                    if (addresses.size() > 0) {
                        Address address = addresses.get(0);
                        adresse[0] = address.getAddressLine(0);
                        adresse[1] = address.getAddressLine(1);
                        adresse[2] = address.getAddressLine(2);
                    }
                    startCamera();
                } catch (IOException e) {
                    Log.e(getClass().getSimpleName(), e.getMessage(), e);
                    Toast.makeText(getActivity(), "Cannot get your adress. Please restart your phone", Toast.LENGTH_LONG).show();
                    NavigationUtil.goToHome(getActivity());
                }
                MarkerOptions marker = new MarkerOptions();
                marker.position(new LatLng(latitude, longitude));
                // marker.anchor(0.5f, 0.5f);
                marker.draggable(false);
                mapView.getMap().addMarker(marker);
                mapView.getMap().getUiSettings().setMyLocationButtonEnabled(false);
                mapView.getMap().getUiSettings().setZoomControlsEnabled(false);
                mapView.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 16));
            }
        }
        new ProfilePictureAsyncTask().execute();
    }

    private boolean isFormCompleted(Location lastLocation) {
        if (lastLocation == null) {
            Toast.makeText(getActivity(), R.string.cannot_get_your_location, Toast.LENGTH_LONG).show();
            return false;
        }
        if (editTextTitle.getText().length() < 4) {
            Toast.makeText(getActivity(), R.string.please_enter_a_longer_title, Toast.LENGTH_LONG).show();
            return false;
        }
        if (!pictureTaken) {
            Toast.makeText(getActivity(), R.string.please_take_a_picture, Toast.LENGTH_LONG).show();
            return false;
        }
        return true;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == FormFragment.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == FragmentActivity.RESULT_OK) {
                new BitmapWorkerTask(imageView).execute(fileUri);
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.suggestion, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_send_suggestion:
            if (isFormCompleted(lastLocation)) {
                boolean isFree = ((Switch) getView().findViewById(R.id.switchfree)).isChecked();
                boolean isOutDoor = ((Switch) getView().findViewById(R.id.switchOutdoor)).isChecked();
                getActivity().startService(
                        UploaderService.newIntent(getActivity(), fileUri.getPath(), editTextTitle.getText().toString(), lastLocation, adresse, isFree,
                                isOutDoor));
                NavigationUtil.goToHome(getActivity());
            }
            break;
        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    private OnClickListener onClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
            case R.id.imageView1:
                startCamera();
                break;
            default:
                break;
            }
        }
    };

    public void startCamera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "FindAPlayground");
        fileUri = Uri.fromFile(f);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    }

    class BitmapWorkerTask extends AsyncTask<Uri, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;

        public BitmapWorkerTask(ImageView imageView) {
            // Use a WeakReference to ensure the ImageView can be garbage
            // collected
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        // Decode image in background.
        @Override
        protected Bitmap doInBackground(Uri... params) {
            fileUri = params[0];
            return BitmapUtil.getResizedBitmap(fileUri);
        }

        // Once complete, see if ImageView is still around and set bitmap.
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (imageViewReference != null && bitmap != null) {
                final ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    imageView.setImageBitmap(bitmap);
                    pictureTaken = true;
                }
            }
        }
    }

    private TextWatcher watcher = new TextWatcher() {

        @Override
        public void afterTextChanged(Editable editable) {
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        }

        @Override
        public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        }

    };

    private class ProfilePictureAsyncTask extends AsyncTask<Void, Void, StreamDrawable> {

        @Override
        protected StreamDrawable doInBackground(Void... params) {
            int cornerRadius = getResources().getInteger(R.integer.small_circle);
            try {
                URL profPict = new URL(FaCConfiguration.getInstance(getActivity()).getSmallProfilePictureUrl(getActivity()));
                Log.i(getClass().getSimpleName(), "Loading image : " + profPict);
                Bitmap mBitmap = BitmapFactory.decodeStream(profPict.openStream());
                StreamDrawable streamDrawable = new StreamDrawable(mBitmap, cornerRadius);
                return streamDrawable;
            } catch (Exception e) {
                Log.e(getClass().getSimpleName(), "Url = " + FaCConfiguration.getInstance(getActivity()).getSmallProfilePictureUrl(getActivity()));
                Log.e(getClass().getSimpleName(), e.getMessage(), e);
                Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.player_logo);
                StreamDrawable streamDrawable = new StreamDrawable(mBitmap, cornerRadius);
                return streamDrawable;
            }
        }

        @Override
        protected void onPostExecute(StreamDrawable result) {
            super.onPostExecute(result);
            imageViewUserProfile.setImageDrawable(result);
        }
    }
}
